﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Objects;
using System.Linq;

using Microsoft.Practices.Unity;

using Arquitetura.Architectural.Model;
using Arquitetura.Architectural.DataLayer;
using Arquitetura.Model;

namespace Arquitetura.DataLayer
{
    public class AlunoData : Data<ArquiteturaModelContainer>, IAlunoData
    {
        #region Constante(s)
        private const string PessoaSetName = "PessoaSet";
        #endregion Constante(s)

        #region Propriedade(s)
        private string QualifiedPessoaSetName
        {
            get
            {
                return QualifyEntitySetName(PessoaSetName);
            }
        }

        private ObjectQuery<Aluno> AlunoSet
        {
            get
            {
                return ObjectQuerySelectFactory<Aluno>(PessoaSetName);
            }
        }

        private ObjectQuery<Mae> MaeSet
        {
            get
            {
                return ObjectQuerySelectFactory<Mae>(PessoaSetName);
            }
        }

        private ObjectQuery<Pai> PaiSet
        {
            get
            {
                return ObjectQuerySelectFactory<Pai>(PessoaSetName);
            }
        }
        #endregion Propriedade(s)

        #region Construtor(es)
        public AlunoData()
            : this(new ArquiteturaModelContainer()) { }

        [InjectionConstructor]
        public AlunoData(ArquiteturaModelContainer arquiteturaModelContainer)
            : base(arquiteturaModelContainer) { }
        #endregion Construtor(es)

        #region Método(s)
        public Resultado<IQueryable<Aluno>> Select()
        {
            try
            {
                return new Resultado<IQueryable<Aluno>>(AlunoSet);
            }
            catch (Exception ex)
            {
                return new Resultado<IQueryable<Aluno>>(ex);
            }
        }

        public Resultado<IQueryable<Aluno>> Select(IEnumerable<string> attributosEntidadeIncluidos)
        {
            try
            {
                return new Resultado<IQueryable<Aluno>>(
                    AlunoSet.Include(attributosEntidadeIncluidos));
            }
            catch (Exception ex)
            {
                return new Resultado<IQueryable<Aluno>>(ex);
            }
        }

        public Resultado<IQueryable<Mae>> SelectMae()
        {
            try
            {
                return new Resultado<IQueryable<Mae>>(MaeSet);
            }
            catch (Exception ex)
            {
                return new Resultado<IQueryable<Mae>>(ex);
            }
        }

        public Resultado<IQueryable<Pai>> SelectPai()
        {
            try
            {
                return new Resultado<IQueryable<Pai>>(PaiSet);
            }
            catch (Exception ex)
            {
                return new Resultado<IQueryable<Pai>>(ex);
            }
        }

        public Resultado InsertAluno(Aluno aluno)
        {
            try
            {
                Mae mae = null;
                Pai pai = null;

                if ((aluno.Mae != null) && (aluno.Mae.Id != 0))
                {
                    mae = aluno.Mae;
                    aluno.Mae = null;
                    aluno.MaeReference.EntityKey = new EntityKey(QualifiedPessoaSetName, "Id", mae.Id);
                }

                if ((aluno.Pai != null) && (aluno.Pai.Id != 0))
                {
                    pai = aluno.Pai;
                    aluno.Pai = null;
                    aluno.PaiReference.EntityKey = new EntityKey(QualifiedPessoaSetName, "Id", pai.Id);
                }

                InsertEntity(aluno, PessoaSetName);

                if (mae != null)
                {
                    aluno.Mae = mae;
                }

                if (pai != null)
                {
                    aluno.Pai = pai;
                }

                return new Resultado(true);
            }
            catch (Exception ex)
            {
                return new Resultado(ex);
            }
        }

        public Resultado UpdateAluno(Aluno aluno)
        {
            try
            {
                UpdateEntity(aluno);
                return new Resultado(true);
            }
            catch (Exception ex)
            {
                return new Resultado(ex);
            }
        }

        public Resultado DeleteAluno(Aluno aluno)
        {
            try
            {
                DeleteEntity(aluno);
                return new Resultado(true);
            }
            catch (Exception ex)
            {
                return new Resultado(ex);
            }

        }

        public Resultado InsertMae(Mae mae)
        {
            try
            {
                InsertEntity(mae, PessoaSetName);
                return new Resultado(true);
            }
            catch (Exception ex)
            {
                return new Resultado(ex);
            }
        }

        public Resultado UpdateMae(Mae mae)
        {
            try
            {
                UpdateEntity(mae);
                return new Resultado(true);
            }
            catch (Exception ex)
            {
                return new Resultado(ex);
            }
        }

        public Resultado InsertPai(Pai pai)
        {
            try
            {
                InsertEntity(pai, PessoaSetName);
                return new Resultado(true);
            }
            catch (Exception ex)
            {
                return new Resultado(ex);
            }
        }

        public Resultado UpdatePai(Pai pai)
        {
            try
            {
                UpdateEntity(pai);
                return new Resultado(true);
            }
            catch (Exception ex)
            {
                return new Resultado(ex);
            }
        }
        #endregion Método(s)
    }
}

